/*
 * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.lang;
import java.util.Random;

import sun.misc.FloatConsts;
import sun.misc.DoubleConsts;

/**
 * {@code Math} 类包含用于执行基本数值运算的方法，如基本指数、对数、
 * 平方根和三角函数。
 *
 * <p>与 {@code StrictMath} 类的某些数值方法不同，{@code Math} 类的
 * 等效函数的所有实现都不要求返回逐位相同的结果。这种放宽允许在不需要
 * 严格可重现性的情况下实现更高性能的实现。
 *
 * <p>默认情况下，许多 {@code Math} 方法只是调用 {@code StrictMath} 中的
 * 等效方法来实现。鼓励代码生成器使用特定于平台的本机库或微处理器指令
 * （如果可用）来提供 {@code Math} 方法的更高性能实现。这种更高性能的
 * 实现仍必须符合 {@code Math} 的规范。
 *
 * <p>实现质量规范涉及两个属性：返回结果的准确性和方法的单调性。
 * 浮点 {@code Math} 方法的准确性以 <i>ulps</i>（最后位置的单位）来衡量。
 * 对于给定的浮点格式，特定实数值的 {@linkplain #ulp(double) ulp} 是
 * 包围该数值的两个浮点值之间的距离。当讨论方法整体的准确性而不是特定
 * 参数的准确性时，引用的ulp数是任何参数的最坏情况误差。如果方法的误差
 * 始终小于0.5 ulps，则该方法始终返回最接近精确结果的浮点数；这种方法是
 * <i>正确舍入的</i>。正确舍入的方法通常是浮点近似能达到的最佳效果；
 * 然而，对于许多浮点方法来说，正确舍入是不切实际的。相反，对于 {@code Math}
 * 类，某些方法允许1或2 ulps的更大误差界限。非正式地说，在1 ulp误差界限下，
 * 当精确结果是可表示的数时，应该返回精确结果作为计算结果；否则，可以返回
 * 包围精确结果的两个浮点值中的任何一个。对于幅度很大的精确结果，括号的
 * 端点之一可能是无穷大。除了单个参数的准确性外，保持方法在不同参数之间的
 * 适当关系也很重要。因此，大多数误差超过0.5 ulp的方法都需要是<i>半单调的</i>：
 * 每当数学函数非递减时，浮点近似也是如此，同样，每当数学函数非递增时，
 * 浮点近似也是如此。并非所有具有1 ulp准确性的近似都会自动满足单调性要求。
 *
 * <p>
 * 平台对int和long基本类型使用有符号二进制补码整数运算。开发人员应该选择
 * 基本类型以确保算术运算始终产生正确的结果，这在某些情况下意味着运算不会
 * 溢出计算值的范围。最佳实践是选择基本类型和算法以避免溢出。在大小为
 * {@code int} 或 {@code long} 且需要检测溢出错误的情况下，方法
 * {@code addExact}、{@code subtractExact}、{@code multiplyExact} 和
 * {@code toIntExact} 在结果溢出时抛出 {@code ArithmeticException}。
 * 对于其他算术运算（如除法、绝对值、递增、递减和取反），溢出仅在特定的
 * 最小值或最大值时发生，应根据情况检查最小值或最大值。
 *
 * @author  unascribed
 * @author  Joseph D. Darcy
 * @since   JDK1.0
 */

public final class Math {

    /**
     * 不允许任何人实例化此类。
     */
    private Math() {}

    /**
     * 最接近自然对数底数 <i>e</i> 的 {@code double} 值。
     */
    public static final double E = 2.7182818284590452354;

    /**
     * 最接近 <i>π</i>（圆的周长与其直径的比值）的 {@code double} 值。
     */
    public static final double PI = 3.14159265358979323846;

    /**
     * 返回角度的三角正弦值。特殊情况：
     * <ul><li>如果参数是NaN或无穷大，则结果是NaN。
     * <li>如果参数是零，则结果是与参数符号相同的零。</ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 结果必须是半单调的。
     *
     * @param   a   角度，以弧度为单位。
     * @return  参数的正弦值。
     */
    public static double sin(double a) {
        return StrictMath.sin(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回角度的三角余弦值。特殊情况：
     * <ul><li>如果参数是NaN或无穷大，则结果是NaN。</ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 结果必须是半单调的。
     *
     * @param   a   角度，以弧度为单位。
     * @return  参数的余弦值。
     */
    public static double cos(double a) {
        return StrictMath.cos(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回角度的三角正切值。特殊情况：
     * <ul><li>如果参数是NaN或无穷大，则结果是NaN。
     * <li>如果参数是零，则结果是与参数符号相同的零。</ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 结果必须是半单调的。
     *
     * @param   a   角度，以弧度为单位。
     * @return  参数的正切值。
     */
    public static double tan(double a) {
        return StrictMath.tan(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回值的反正弦；返回的角度在 -<i>π</i>/2 到 <i>π</i>/2 的范围内。特殊情况：
     * <ul><li>如果参数是NaN或其绝对值大于1，则结果是NaN。
     * <li>如果参数是零，则结果是与参数符号相同的零。</ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 结果必须是半单调的。
     *
     * @param   a   要返回其反正弦的值。
     * @return  参数的反正弦。
     */
    public static double asin(double a) {
        return StrictMath.asin(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回值的反余弦；返回的角度在 0.0 到 <i>π</i> 的范围内。特殊情况：
     * <ul><li>如果参数是NaN或其绝对值大于1，则结果是NaN。</ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 结果必须是半单调的。
     *
     * @param   a   要返回其反余弦的值。
     * @return  参数的反余弦。
     */
    public static double acos(double a) {
        return StrictMath.acos(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回值的反正切；返回的角度在 -<i>π</i>/2 到 <i>π</i>/2 的范围内。特殊情况：
     * <ul><li>如果参数是NaN，则结果是NaN。
     * <li>如果参数是零，则结果是与参数符号相同的零。</ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 结果必须是半单调的。
     *
     * @param   a   要返回其反正切的值。
     * @return  参数的反正切。
     */
    public static double atan(double a) {
        return StrictMath.atan(a); // default impl. delegates to StrictMath
    }

    /**
     * 将以度为单位测量的角度转换为以弧度为单位测量的近似等效角度。
     * 从度到弧度的转换通常是不精确的。
     *
     * @param   angdeg   角度，以度为单位
     * @return  角度 {@code angdeg} 以弧度为单位的测量值。
     * @since   1.2
     */
    public static double toRadians(double angdeg) {
        return angdeg / 180.0 * PI;
    }

    /**
     * 将以弧度为单位测量的角度转换为以度为单位测量的近似等效角度。
     * 从弧度到度的转换通常是不精确的；用户<i>不应</i>期望 
     * {@code cos(toRadians(90.0))} 完全等于 {@code 0.0}。
     *
     * @param   angrad   角度，以弧度为单位
     * @return  角度 {@code angrad} 以度为单位的测量值。
     * @since   1.2
     */
    public static double toDegrees(double angrad) {
        return angrad * 180.0 / PI;
    }

    /**
     * 返回欧拉数 <i>e</i> 的 {@code double} 值次幂。特殊情况：
     * <ul><li>如果参数是NaN，则结果是NaN。
     * <li>如果参数是正无穷大，则结果是正无穷大。
     * <li>如果参数是负无穷大，则结果是正零。</ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 结果必须是半单调的。
     *
     * @param   a   <i>e</i> 的指数。
     * @return  值 <i>e</i><sup>{@code a}</sup>，其中 <i>e</i> 是自然对数的底数。
     */
    public static double exp(double a) {
        return StrictMath.exp(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回 {@code double} 值的自然对数（以 <i>e</i> 为底）。特殊情况：
     * <ul><li>如果参数是NaN或小于零，则结果是NaN。
     * <li>如果参数是正无穷大，则结果是正无穷大。
     * <li>如果参数是正零或负零，则结果是负无穷大。</ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 结果必须是半单调的。
     *
     * @param   a   一个值
     * @return  值 ln&nbsp;{@code a}，{@code a} 的自然对数。
     */
    public static double log(double a) {
        return StrictMath.log(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回 {@code double} 值的以10为底的对数。特殊情况：
     *
     * <ul><li>如果参数是NaN或小于零，则结果是NaN。
     * <li>如果参数是正无穷大，则结果是正无穷大。
     * <li>如果参数是正零或负零，则结果是负无穷大。
     * <li>如果参数等于10<sup><i>n</i></sup>（其中<i>n</i>为整数），则结果是<i>n</i>。
     * </ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 结果必须是半单调的。
     *
     * @param   a   一个值
     * @return  {@code a} 的以10为底的对数。
     * @since 1.5
     */
    public static double log10(double a) {
        return StrictMath.log10(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回 {@code double} 值的正确舍入的正平方根。特殊情况：
     * <ul><li>如果参数是NaN或小于零，则结果是NaN。
     * <li>如果参数是正无穷大，则结果是正无穷大。
     * <li>如果参数是正零或负零，则结果与参数相同。</ul>
     * 否则，结果是最接近参数值的真实数学平方根的 {@code double} 值。
     *
     * @param   a   一个值。
     * @return  {@code a} 的正平方根。
     *          如果参数是NaN或小于零，则结果是NaN。
     */
    public static double sqrt(double a) {
        return StrictMath.sqrt(a); // default impl. delegates to StrictMath
                                   // 注意硬件sqrt指令
                                   // 经常可以被JIT直接使用
                                   // 应该比在软件中执行Math.sqrt快得多。
    }


    /**
     * 返回 {@code double} 值的立方根。对于正有限值 {@code x}，
     * {@code cbrt(-x) == -cbrt(x)}；也就是说，负值的立方根是
     * 该值大小的立方根的负值。
     *
     * 特殊情况：
     *
     * <ul>
     *
     * <li>如果参数是NaN，则结果是NaN。
     *
     * <li>如果参数是无穷大，则结果是与参数符号相同的无穷大。
     *
     * <li>如果参数是零，则结果是与参数符号相同的零。
     *
     * </ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     *
     * @param   a   一个值。
     * @return  {@code a} 的立方根。
     * @since 1.5
     */
    public static double cbrt(double a) {
        return StrictMath.cbrt(a);
    }

    /**
     * 按照IEEE 754标准规定计算两个参数的余数运算。
     * 余数值在数学上等于
     * <code>f1&nbsp;-&nbsp;f2</code>&nbsp;&times;&nbsp;<i>n</i>，
     * 其中<i>n</i>是最接近商{@code f1/f2}精确数学值的数学整数，
     * 如果两个数学整数与{@code f1/f2}同样接近，
     * 则<i>n</i>是偶数整数。如果余数为零，其符号与第一个参数的符号相同。
     * 特殊情况：
     * <ul><li>如果任一参数是NaN，或第一个参数是无穷大，
     * 或第二个参数是正零或负零，则结果是NaN。
     * <li>如果第一个参数是有限的且第二个参数是无穷大，
     * 则结果与第一个参数相同。</ul>
     *
     * @param   f1   被除数。
     * @param   f2   除数。
     * @return  {@code f1} 除以 {@code f2} 的余数。
     */
    public static double IEEEremainder(double f1, double f2) {
        return StrictMath.IEEEremainder(f1, f2); // delegate to StrictMath
    }

    /**
     * 返回大于或等于参数且等于数学整数的最小（最接近负无穷大）
     * {@code double} 值。特殊情况：
     * <ul><li>如果参数值已经等于数学整数，则结果与参数相同。
     * <li>如果参数是NaN或无穷大或正零或负零，则结果与参数相同。
     * <li>如果参数值小于零但大于-1.0，则结果是负零。</ul>
     * 注意 {@code Math.ceil(x)} 的值恰好是 {@code -Math.floor(-x)} 的值。
     *
     *
     * @param   a   一个值。
     * @return  大于或等于参数且等于数学整数的最小（最接近负无穷大）浮点值。
     */
    public static double ceil(double a) {
        return StrictMath.ceil(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回小于或等于参数且等于数学整数的最大（最接近正无穷大）
     * {@code double} 值。特殊情况：
     * <ul><li>如果参数值已经等于数学整数，则结果与参数相同。
     * <li>如果参数是NaN或无穷大或正零或负零，则结果与参数相同。</ul>
     *
     * @param   a   一个值。
     * @return  小于或等于参数且等于数学整数的最大（最接近正无穷大）浮点值。
     */
    public static double floor(double a) {
        return StrictMath.floor(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回最接近参数值且等于数学整数的 {@code double} 值。
     * 如果两个作为数学整数的 {@code double} 值同样接近，
     * 则结果是偶数整数值。特殊情况：
     * <ul><li>如果参数值已经等于数学整数，则结果与参数相同。
     * <li>如果参数是NaN或无穷大或正零或负零，则结果与参数相同。</ul>
     *
     * @param   a   一个 {@code double} 值。
     * @return  最接近 {@code a} 且等于数学整数的浮点值。
     */
    public static double rint(double a) {
        return StrictMath.rint(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回从直角坐标 ({@code x},&nbsp;{@code y}) 转换为极坐标
     * (r,&nbsp;<i>theta</i>) 的角度 <i>theta</i>。
     * 此方法通过计算 {@code y/x} 在 -<i>π</i> 到 <i>π</i> 范围内的反正切来计算相位 <i>theta</i>。
     * 特殊情况：
     * <ul><li>如果任一参数是NaN，则结果是NaN。
     * <li>如果第一个参数是正零且第二个参数是正数，或第一个参数是正有限数且
     * 第二个参数是正无穷大，则结果是正零。
     * <li>如果第一个参数是负零且第二个参数是正数，或第一个参数是负有限数且
     * 第二个参数是正无穷大，则结果是负零。
     * <li>如果第一个参数是正零且第二个参数是负数，或第一个参数是正有限数且
     * 第二个参数是负无穷大，则结果是最接近 <i>π</i> 的 {@code double} 值。
     * <li>如果第一个参数是负零且第二个参数是负数，或第一个参数是负有限数且
     * 第二个参数是负无穷大，则结果是最接近 -<i>π</i> 的 {@code double} 值。
     * <li>如果第一个参数是正数且第二个参数是正零或负零，或第一个参数是正无穷大且
     * 第二个参数是有限的，则结果是最接近 <i>π</i>/2 的 {@code double} 值。
     * <li>如果第一个参数是负数且第二个参数是正零或负零，或第一个参数是负无穷大且
     * 第二个参数是有限的，则结果是最接近 -<i>π</i>/2 的 {@code double} 值。
     * <li>如果两个参数都是正无穷大，则结果是最接近 <i>π</i>/4 的 {@code double} 值。
     * <li>如果第一个参数是正无穷大且第二个参数是负无穷大，则结果是
     * 最接近 3*<i>π</i>/4 的 {@code double} 值。
     * <li>如果第一个参数是负无穷大且第二个参数是正无穷大，则结果是
     * 最接近 -<i>π</i>/4 的 {@code double} 值。
     * <li>如果两个参数都是负无穷大，则结果是最接近 -3*<i>π</i>/4 的 {@code double} 值。</ul>
     *
     * <p>计算结果必须在精确结果的2 ulps范围内。
     * 结果必须是半单调的。
     *
     * @param   y   纵坐标
     * @param   x   横坐标
     * @return  极坐标中点 (<i>r</i>,&nbsp;<i>theta</i>) 的 <i>theta</i> 分量，
     *          对应于笛卡尔坐标中的点 (<i>x</i>,&nbsp;<i>y</i>)。
     */
    public static double atan2(double y, double x) {
        return StrictMath.atan2(y, x); // default impl. delegates to StrictMath
    }

    /**
     * 返回第一个参数的第二个参数次幂的值。特殊情况：
     *
     * <ul><li>如果第二个参数是正零或负零，则结果是1.0。
     * <li>如果第二个参数是1.0，则结果与第一个参数相同。
     * <li>如果第二个参数是NaN，则结果是NaN。
     * <li>如果第一个参数是NaN且第二个参数非零，则结果是NaN。
     *
     * <li>如果
     * <ul>
     * <li>第一个参数的绝对值大于1且第二个参数是正无穷大，或
     * <li>第一个参数的绝对值小于1且第二个参数是负无穷大，
     * </ul>
     * 则结果是正无穷大。
     *
     * <li>如果
     * <ul>
     * <li>第一个参数的绝对值大于1且第二个参数是负无穷大，或
     * <li>第一个参数的绝对值小于1且第二个参数是正无穷大，
     * </ul>
     * 则结果是正零。
     *
     * <li>如果第一个参数的绝对值等于1且第二个参数是无穷大，则结果是NaN。
     *
     * <li>如果
     * <ul>
     * <li>第一个参数是正零且第二个参数大于零，或
     * <li>第一个参数是正无穷大且第二个参数小于零，
     * </ul>
     * 则结果是正零。
     *
     * <li>如果
     * <ul>
     * <li>第一个参数是正零且第二个参数小于零，或
     * <li>第一个参数是正无穷大且第二个参数大于零，
     * </ul>
     * 则结果是正无穷大。
     *
     * <li>如果
     * <ul>
     * <li>第一个参数是负零且第二个参数大于零但不是有限奇整数，或
     * <li>第一个参数是负无穷大且第二个参数小于零但不是有限奇整数，
     * </ul>
     * 则结果是正零。
     *
     * <li>如果
     * <ul>
     * <li>第一个参数是负零且第二个参数是正有限奇整数，或
     * <li>第一个参数是负无穷大且第二个参数是负有限奇整数，
     * </ul>
     * 则结果是负零。
     *
     * <li>如果
     * <ul>
     * <li>第一个参数是负零且第二个参数小于零但不是有限奇整数，或
     * <li>第一个参数是负无穷大且第二个参数大于零但不是有限奇整数，
     * </ul>
     * 则结果是正无穷大。
     *
     * <li>如果
     * <ul>
     * <li>第一个参数是负零且第二个参数是负有限奇整数，或
     * <li>第一个参数是负无穷大且第二个参数是正有限奇整数，
     * </ul>
     * 则结果是负无穷大。
     *
     * <li>如果第一个参数是有限的且小于零
     * <ul>
     * <li>如果第二个参数是有限偶整数，结果等于第一个参数绝对值的
     * 第二个参数次幂的结果
     *
     * <li>如果第二个参数是有限奇整数，结果等于第一个参数绝对值的
     * 第二个参数次幂结果的负值
     *
     * <li>如果第二个参数是有限的但不是整数，则结果是NaN。
     * </ul>
     *
     * <li>如果两个参数都是整数，则结果恰好等于第一个参数的第二个参数次幂的
     * 数学结果，如果该结果实际上可以精确表示为 {@code double} 值。</ul>
     *
     * <p>（在上述描述中，当且仅当浮点值是有限的且是方法 {@link #ceil ceil} 的
     * 不动点，或等价地，是方法 {@link #floor floor} 的不动点时，
     * 该浮点值被认为是整数。当且仅当将方法应用于值的结果等于该值时，
     * 该值是单参数方法的不动点。）
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 结果必须是半单调的。
     *
     * @param   a   底数。
     * @param   b   指数。
     * @return  值 {@code a}<sup>{@code b}</sup>。
     */
    public static double pow(double a, double b) {
        return StrictMath.pow(a, b); // default impl. delegates to StrictMath
    }

    /**
     * 返回最接近参数的 {@code int}，平局时向正无穷大舍入。
     *
     * <p>
     * 特殊情况：
     * <ul><li>如果参数是 NaN，结果是 0。
     * <li>如果参数是负无穷大或任何小于或等于 {@code Integer.MIN_VALUE} 值的值，
     * 结果等于 {@code Integer.MIN_VALUE} 的值。
     * <li>如果参数是正无穷大或任何大于或等于 {@code Integer.MAX_VALUE} 值的值，
     * 结果等于 {@code Integer.MAX_VALUE} 的值。</ul>
     *
     * @param   a   要舍入为整数的浮点值。
     * @return  参数舍入到最接近的 {@code int} 值。
     * @see     java.lang.Integer#MAX_VALUE
     * @see     java.lang.Integer#MIN_VALUE
     */
    public static int round(float a) {
        int intBits = Float.floatToRawIntBits(a);
        int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK)
                >> (FloatConsts.SIGNIFICAND_WIDTH - 1);
        int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2
                + FloatConsts.EXP_BIAS) - biasedExp;
        if ((shift & -32) == 0) { // shift >= 0 && shift < 32
            // a is a finite number such that pow(2,-32) <= ulp(a) < 1
            int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK)
                    | (FloatConsts.SIGNIF_BIT_MASK + 1));
            if (intBits < 0) {
                r = -r;
            }
            // In the comments below each Java expression evaluates to the value
            // the corresponding mathematical expression:
            // (r) evaluates to a / ulp(a)
            // (r >> shift) evaluates to floor(a * 2)
            // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
            // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
            return ((r >> shift) + 1) >> 1;
        } else {
            // a is either
            // - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2
            // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
            // - an infinity or NaN
            return (int) a;
        }
    }

    /**
     * 返回最接近参数的 {@code long}，平局时向正无穷大舍入。
     *
     * <p>特殊情况：
     * <ul><li>如果参数是NaN，结果是0。
     * <li>如果参数是负无穷大或任何小于或等于 {@code Long.MIN_VALUE} 值的值，
     * 结果等于 {@code Long.MIN_VALUE} 的值。
     * <li>如果参数是正无穷大或任何大于或等于 {@code Long.MAX_VALUE} 值的值，
     * 结果等于 {@code Long.MAX_VALUE} 的值。</ul>
     *
     * @param   a   要舍入为 {@code long} 的浮点值。
     * @return  参数舍入到最接近的 {@code long} 值。
     * @see     java.lang.Long#MAX_VALUE
     * @see     java.lang.Long#MIN_VALUE
     */
    public static long round(double a) {
        long longBits = Double.doubleToRawLongBits(a);
        long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK)
                >> (DoubleConsts.SIGNIFICAND_WIDTH - 1);
        long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2
                + DoubleConsts.EXP_BIAS) - biasedExp;
        if ((shift & -64) == 0) { // shift >= 0 && shift < 64
            // a is a finite number such that pow(2,-64) <= ulp(a) < 1
            long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK)
                    | (DoubleConsts.SIGNIF_BIT_MASK + 1));
            if (longBits < 0) {
                r = -r;
            }
            // In the comments below each Java expression evaluates to the value
            // the corresponding mathematical expression:
            // (r) evaluates to a / ulp(a)
            // (r >> shift) evaluates to floor(a * 2)
            // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
            // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
            return ((r >> shift) + 1) >> 1;
        } else {
            // a is either
            // - a finite number with abs(a) < exp(2,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2
            // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
            // - an infinity or NaN
            return (long) a;
        }
    }

    private static final class RandomNumberGeneratorHolder {
        static final Random randomNumberGenerator = new Random();
    }

    /**
     * 返回一个带正号的 {@code double} 值，大于或等于 {@code 0.0} 且小于 {@code 1.0}。
     * 返回值是从该范围内以（近似）均匀分布伪随机选择的。
     *
     * <p>当首次调用此方法时，它会创建一个新的伪随机数生成器，
     * 就像通过表达式
     *
     * <blockquote>{@code new java.util.Random()}</blockquote>
     *
     * 此后，这个新的伪随机数生成器用于此方法的所有调用，
     * 并且不在其他地方使用。
     *
     * <p>此方法经过适当同步，允许多个线程正确使用。
     * 但是，如果许多线程需要以很高的速率生成伪随机数，
     * 让每个线程拥有自己的伪随机数生成器可能会减少争用。
     *
     * @return  一个大于或等于 {@code 0.0} 且小于 {@code 1.0} 的伪随机 {@code double}。
     * @see Random#nextDouble()
     */
    public static double random() {
        return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
    }

    /**
     * 返回其参数的和，如果结果溢出 {@code int} 则抛出异常。
     *
     * @param x 第一个值
     * @param y 第二个值
     * @return 结果
     * @throws ArithmeticException 如果结果溢出int
     * @since 1.8
     */
    public static int addExact(int x, int y) {
        int r = x + y;
        // HD 2-12 Overflow iff both arguments have the opposite sign of the result
        if (((x ^ r) & (y ^ r)) < 0) {
            throw new ArithmeticException("integer overflow");
        }
        return r;
    }

    /**
     * 返回其参数的和，如果结果溢出 {@code long} 则抛出异常。
     *
     * @param x 第一个值
     * @param y 第二个值
     * @return 结果
     * @throws ArithmeticException 如果结果溢出long
     * @since 1.8
     */
    public static long addExact(long x, long y) {
        long r = x + y;
        // HD 2-12 Overflow iff both arguments have the opposite sign of the result
        if (((x ^ r) & (y ^ r)) < 0) {
            throw new ArithmeticException("long overflow");
        }
        return r;
    }

    /**
     * 返回参数的差，如果结果溢出 {@code int} 则抛出异常。
     *
     * @param x 第一个值
     * @param y 要从第一个值中减去的第二个值
     * @return 结果
     * @throws ArithmeticException 如果结果溢出int
     * @since 1.8
     */
    public static int subtractExact(int x, int y) {
        int r = x - y;
        // HD 2-12 Overflow iff the arguments have different signs and
        // the sign of the result is different than the sign of x
        if (((x ^ y) & (x ^ r)) < 0) {
            throw new ArithmeticException("integer overflow");
        }
        return r;
    }

    /**
     * 返回参数的差，如果结果溢出 {@code long} 则抛出异常。
     *
     * @param x 第一个值
     * @param y 要从第一个值中减去的第二个值
     * @return 结果
     * @throws ArithmeticException 如果结果溢出long
     * @since 1.8
     */
    public static long subtractExact(long x, long y) {
        long r = x - y;
        // HD 2-12 Overflow iff the arguments have different signs and
        // the sign of the result is different than the sign of x
        if (((x ^ y) & (x ^ r)) < 0) {
            throw new ArithmeticException("long overflow");
        }
        return r;
    }

    /**
     * 返回参数的乘积，如果结果溢出 {@code int} 则抛出异常。
     *
     * @param x 第一个值
     * @param y 第二个值
     * @return 结果
     * @throws ArithmeticException 如果结果溢出int
     * @since 1.8
     */
    public static int multiplyExact(int x, int y) {
        long r = (long)x * (long)y;
        if ((int)r != r) {
            throw new ArithmeticException("integer overflow");
        }
        return (int)r;
    }

    /**
     * 返回参数的乘积，如果结果溢出 {@code long} 则抛出异常。
     *
     * @param x 第一个值
     * @param y 第二个值
     * @return 结果
     * @throws ArithmeticException 如果结果溢出long
     * @since 1.8
     */
    public static long multiplyExact(long x, long y) {
        long r = x * y;
        long ax = Math.abs(x);
        long ay = Math.abs(y);
        if (((ax | ay) >>> 31 != 0)) {
            // Some bits greater than 2^31 that might cause overflow
            // Check the result using the divide operator
            // and check for the special case of Long.MIN_VALUE * -1
           if (((y != 0) && (r / y != x)) ||
               (x == Long.MIN_VALUE && y == -1)) {
                throw new ArithmeticException("long overflow");
            }
        }
        return r;
    }

    /**
     * 返回参数加一的结果，如果结果溢出 {@code int} 则抛出异常。
     *
     * @param a 要递增的值
     * @return 结果
     * @throws ArithmeticException 如果结果溢出int
     * @since 1.8
     */
    public static int incrementExact(int a) {
        if (a == Integer.MAX_VALUE) {
            throw new ArithmeticException("integer overflow");
        }

        return a + 1;
    }

    /**
     * 返回参数加一的结果，如果结果溢出 {@code long} 则抛出异常。
     *
     * @param a 要递增的值
     * @return 结果
     * @throws ArithmeticException 如果结果溢出long
     * @since 1.8
     */
    public static long incrementExact(long a) {
        if (a == Long.MAX_VALUE) {
            throw new ArithmeticException("long overflow");
        }

        return a + 1L;
    }

    /**
     * 返回参数减一的结果，如果结果溢出 {@code int} 则抛出异常。
     *
     * @param a 要递减的值
     * @return 结果
     * @throws ArithmeticException 如果结果溢出int
     * @since 1.8
     */
    public static int decrementExact(int a) {
        if (a == Integer.MIN_VALUE) {
            throw new ArithmeticException("integer overflow");
        }

        return a - 1;
    }

    /**
     * 返回参数减一的结果，如果结果溢出 {@code long} 则抛出异常。
     *
     * @param a 要递减的值
     * @return 结果
     * @throws ArithmeticException 如果结果溢出long
     * @since 1.8
     */
    public static long decrementExact(long a) {
        if (a == Long.MIN_VALUE) {
            throw new ArithmeticException("long overflow");
        }

        return a - 1L;
    }

    /**
     * 返回参数的负值，如果结果溢出 {@code int} 则抛出异常。
     *
     * @param a 要取负的值
     * @return 结果
     * @throws ArithmeticException 如果结果溢出int
     * @since 1.8
     */
    public static int negateExact(int a) {
        if (a == Integer.MIN_VALUE) {
            throw new ArithmeticException("integer overflow");
        }

        return -a;
    }

    /**
     * 返回参数的负值，如果结果溢出 {@code long} 则抛出异常。
     *
     * @param a 要取负的值
     * @return 结果
     * @throws ArithmeticException 如果结果溢出long
     * @since 1.8
     */
    public static long negateExact(long a) {
        if (a == Long.MIN_VALUE) {
            throw new ArithmeticException("long overflow");
        }

        return -a;
    }

    /**
     * 返回 {@code long} 参数的值；如果值溢出 {@code int} 则抛出异常。
     *
     * @param value long值
     * @return 作为int的参数
     * @throws ArithmeticException 如果 {@code argument} 溢出int
     * @since 1.8
     */
    public static int toIntExact(long value) {
        if ((int)value != value) {
            throw new ArithmeticException("integer overflow");
        }
        return (int)value;
    }

    /**
     * 返回小于或等于代数商的最大（最接近正无穷大）{@code int} 值。
     * 有一种特殊情况，如果被除数是 {@linkplain Integer#MIN_VALUE Integer.MIN_VALUE}
     * 且除数是 {@code -1}，则发生整数溢出，结果等于 {@code Integer.MIN_VALUE}。
     * <p>
     * 正常的整数除法在向零舍入模式（截断）下操作。
     * 此操作改为在向负无穷大舍入（向下取整）模式下操作。
     * 当精确结果为负数时，向下取整舍入模式给出与截断不同的结果。
     * <ul>
     *   <li>如果参数的符号相同，{@code floorDiv} 和 {@code /} 运算符的结果相同。<br>
     *       例如，{@code floorDiv(4, 3) == 1} 且 {@code (4 / 3) == 1}。</li>
     *   <li>如果参数的符号不同，商为负数，{@code floorDiv} 返回小于或等于商的整数，
     *       而 {@code /} 运算符返回最接近零的整数。<br>
     *       例如，{@code floorDiv(-4, 3) == -2}，
     *       而 {@code (-4 / 3) == -1}。
     *   </li>
     * </ul>
     * <p>
     *
     * @param x 被除数
     * @param y 除数
     * @return 小于或等于代数商的最大（最接近正无穷大）{@code int} 值。
     * @throws ArithmeticException 如果除数 {@code y} 为零
     * @see #floorMod(int, int)
     * @see #floor(double)
     * @since 1.8
     */
    public static int floorDiv(int x, int y) {
        int r = x / y;
        // if the signs are different and modulo not zero, round down
        if ((x ^ y) < 0 && (r * y != x)) {
            r--;
        }
        return r;
    }

    /**
     * 返回小于或等于代数商的最大（最接近正无穷大）{@code long} 值。
     * 有一种特殊情况，如果被除数是 {@linkplain Long#MIN_VALUE Long.MIN_VALUE}
     * 且除数是 {@code -1}，则发生整数溢出，结果等于 {@code Long.MIN_VALUE}。
     * <p>
     * 正常的整数除法在向零舍入模式（截断）下操作。
     * 此操作改为在向负无穷大舍入（向下取整）模式下操作。
     * 当精确结果为负数时，向下取整舍入模式给出与截断不同的结果。
     * <p>
     * 有关示例，请参见 {@link #floorDiv(int, int)}。
     *
     * @param x 被除数
     * @param y 除数
     * @return 小于或等于代数商的最大（最接近正无穷大）{@code long} 值。
     * @throws ArithmeticException 如果除数 {@code y} 为零
     * @see #floorMod(long, long)
     * @see #floor(double)
     * @since 1.8
     */
    public static long floorDiv(long x, long y) {
        long r = x / y;
        // if the signs are different and modulo not zero, round down
        if ((x ^ y) < 0 && (r * y != x)) {
            r--;
        }
        return r;
    }

    /**
     * 返回 {@code int} 参数的向下取整模数。
     * <p>
     * 向下取整模数是 {@code x - (floorDiv(x, y) * y)}，
     * 与除数 {@code y} 具有相同的符号，
     * 并且在 {@code -abs(y) < r < +abs(y)} 范围内。
     *
     * <p>
     * {@code floorDiv} 和 {@code floorMod} 之间的关系是：
     * <ul>
     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
     * </ul>
     * <p>
     * {@code floorMod} 和 {@code %} 运算符之间的值差异是由于
     * {@code floorDiv} 返回小于或等于商的整数，
     * 而 {@code /} 运算符返回最接近零的整数。
     * <p>
     * 示例：
     * <ul>
     *   <li>如果参数的符号相同，{@code floorMod} 和 {@code %} 运算符的结果相同。<br>
     *       <ul>
     *       <li>{@code floorMod(4, 3) == 1}; &nbsp; 且 {@code (4 % 3) == 1}</li>
     *       </ul>
     *   <li>如果参数的符号不同，结果与 {@code %} 运算符不同。<br>
     *      <ul>
     *      <li>{@code floorMod(+4, -3) == -2}; &nbsp; 且 {@code (+4 % -3) == +1} </li>
     *      <li>{@code floorMod(-4, +3) == +2}; &nbsp; 且 {@code (-4 % +3) == -1} </li>
     *      <li>{@code floorMod(-4, -3) == -1}; &nbsp; 且 {@code (-4 % -3) == -1 } </li>
     *      </ul>
     *   </li>
     * </ul>
     * <p>
     * 如果参数的符号未知且需要正模数，
     * 可以计算为 {@code (floorMod(x, y) + abs(y)) % abs(y)}。
     *
     * @param x 被除数
     * @param y 除数
     * @return 向下取整模数 {@code x - (floorDiv(x, y) * y)}
     * @throws ArithmeticException 如果除数 {@code y} 为零
     * @see #floorDiv(int, int)
     * @since 1.8
     */
    public static int floorMod(int x, int y) {
        int r = x - floorDiv(x, y) * y;
        return r;
    }

    /**
     * 返回 {@code long} 参数的向下取整模数。
     * <p>
     * 向下取整模数是 {@code x - (floorDiv(x, y) * y)}，
     * 与除数 {@code y} 具有相同的符号，
     * 并且在 {@code -abs(y) < r < +abs(y)} 范围内。
     *
     * <p>
     * {@code floorDiv} 和 {@code floorMod} 之间的关系是：
     * <ul>
     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
     * </ul>
     * <p>
     * 有关示例，请参见 {@link #floorMod(int, int)}。
     *
     * @param x 被除数
     * @param y 除数
     * @return 向下取整模数 {@code x - (floorDiv(x, y) * y)}
     * @throws ArithmeticException 如果除数 {@code y} 为零
     * @see #floorDiv(long, long)
     * @since 1.8
     */
    public static long floorMod(long x, long y) {
        return x - floorDiv(x, y) * y;
    }

    /**
     * 返回 {@code int} 值的绝对值。
     * 如果参数不是负数，则返回参数。
     * 如果参数是负数，则返回参数的负值。
     *
     * <p>注意，如果参数等于 {@link Integer#MIN_VALUE} 的值，
     * 即最负的可表示 {@code int} 值，结果是相同的值，仍然是负数。
     *
     * @param   a   要确定绝对值的参数
     * @return  参数的绝对值。
     */
    public static int abs(int a) {
        return (a < 0) ? -a : a;
    }

    /**
     * 返回 {@code long} 值的绝对值。
     * 如果参数不是负数，则返回参数。
     * 如果参数是负数，则返回参数的负值。
     *
     * <p>注意，如果参数等于 {@link Long#MIN_VALUE} 的值，
     * 即最负的可表示 {@code long} 值，结果是相同的值，仍然是负数。
     *
     * @param   a   要确定绝对值的参数
     * @return  参数的绝对值。
     */
    public static long abs(long a) {
        return (a < 0) ? -a : a;
    }

    /**
     * 返回 {@code float} 值的绝对值。
     * 如果参数不是负数，则返回参数。
     * 如果参数是负数，则返回参数的负值。
     * 特殊情况：
     * <ul><li>如果参数是正零或负零，结果是正零。
     * <li>如果参数是无穷大，结果是正无穷大。
     * <li>如果参数是NaN，结果是NaN。</ul>
     * 换句话说，结果与以下表达式的值相同：
     * <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
     *
     * @param   a   要确定绝对值的参数
     * @return  参数的绝对值。
     */
    public static float abs(float a) {
        return (a <= 0.0F) ? 0.0F - a : a;
    }

    /**
     * 返回 {@code double} 值的绝对值。
     * 如果参数不是负数，则返回参数。
     * 如果参数是负数，则返回参数的负值。
     * 特殊情况：
     * <ul><li>如果参数是正零或负零，结果是正零。
     * <li>如果参数是无穷大，结果是正无穷大。
     * <li>如果参数是NaN，结果是NaN。</ul>
     * 换句话说，结果与以下表达式的值相同：
     * <p>{@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)}
     *
     * @param   a   要确定绝对值的参数
     * @return  参数的绝对值。
     */
    public static double abs(double a) {
        return (a <= 0.0D) ? 0.0D - a : a;
    }

    /**
     * 返回两个 {@code int} 值中较大的一个。也就是说，
     * 结果是更接近 {@link Integer#MAX_VALUE} 值的参数。
     * 如果参数具有相同的值，结果是相同的值。
     *
     * @param   a   一个参数。
     * @param   b   另一个参数。
     * @return  {@code a} 和 {@code b} 中较大的一个。
     */
    public static int max(int a, int b) {
        return (a >= b) ? a : b;
    }

    /**
     * 返回两个 {@code long} 值中较大的一个。也就是说，
     * 结果是更接近 {@link Long#MAX_VALUE} 值的参数。
     * 如果参数具有相同的值，结果是相同的值。
     *
     * @param   a   一个参数。
     * @param   b   另一个参数。
     * @return  {@code a} 和 {@code b} 中较大的一个。
     */
    public static long max(long a, long b) {
        return (a >= b) ? a : b;
    }

    // Use raw bit-wise conversions on guaranteed non-NaN arguments.
    private static long negativeZeroFloatBits  = Float.floatToRawIntBits(-0.0f);
    private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);

    /**
     * 返回两个 {@code float} 值中较大的一个。也就是说，
     * 结果是更接近正无穷大的参数。如果参数具有相同的值，
     * 结果是相同的值。如果任一值是NaN，则结果是NaN。
     * 与数值比较运算符不同，此方法认为负零严格小于正零。
     * 如果一个参数是正零，另一个是负零，结果是正零。
     *
     * @param   a   一个参数。
     * @param   b   另一个参数。
     * @return  {@code a} 和 {@code b} 中较大的一个。
     */
    public static float max(float a, float b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0f) &&
            (b == 0.0f) &&
            (Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a >= b) ? a : b;
    }

    /**
     * 返回两个 {@code double} 值中较大的一个。也就是说，
     * 结果是更接近正无穷大的参数。如果参数具有相同的值，
     * 结果是相同的值。如果任一值是NaN，则结果是NaN。
     * 与数值比较运算符不同，此方法认为负零严格小于正零。
     * 如果一个参数是正零，另一个是负零，结果是正零。
     *
     * @param   a   一个参数。
     * @param   b   另一个参数。
     * @return  {@code a} 和 {@code b} 中较大的一个。
     */
    public static double max(double a, double b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0d) &&
            (b == 0.0d) &&
            (Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a >= b) ? a : b;
    }

    /**
     * 返回两个 {@code int} 值中较小的一个。也就是说，
     * 结果是更接近 {@link Integer#MIN_VALUE} 值的参数。
     * 如果参数具有相同的值，结果是相同的值。
     *
     * @param   a   一个参数。
     * @param   b   另一个参数。
     * @return  {@code a} 和 {@code b} 中较小的一个。
     */
    public static int min(int a, int b) {
        return (a <= b) ? a : b;
    }

    /**
     * 返回两个 {@code long} 值中较小的一个。也就是说，
     * 结果是更接近 {@link Long#MIN_VALUE} 值的参数。
     * 如果参数具有相同的值，结果是相同的值。
     *
     * @param   a   一个参数。
     * @param   b   另一个参数。
     * @return  {@code a} 和 {@code b} 中较小的一个。
     */
    public static long min(long a, long b) {
        return (a <= b) ? a : b;
    }

    /**
     * 返回两个 {@code float} 值中较小的一个。也就是说，
     * 结果是更接近负无穷大的值。如果参数具有相同的值，
     * 结果是相同的值。如果任一值是NaN，则结果是NaN。
     * 与数值比较运算符不同，此方法认为负零严格小于正零。
     * 如果一个参数是正零，另一个是负零，结果是负零。
     *
     * @param   a   一个参数。
     * @param   b   另一个参数。
     * @return  {@code a} 和 {@code b} 中较小的一个。
     */
    public static float min(float a, float b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0f) &&
            (b == 0.0f) &&
            (Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a <= b) ? a : b;
    }

    /**
     * 返回两个 {@code double} 值中较小的一个。也就是说，
     * 结果是更接近负无穷大的值。如果参数具有相同的值，
     * 结果是相同的值。如果任一值是NaN，则结果是NaN。
     * 与数值比较运算符不同，此方法认为负零严格小于正零。
     * 如果一个参数是正零，另一个是负零，结果是负零。
     *
     * @param   a   一个参数。
     * @param   b   另一个参数。
     * @return  {@code a} 和 {@code b} 中较小的一个。
     */
    public static double min(double a, double b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0d) &&
            (b == 0.0d) &&
            (Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a <= b) ? a : b;
    }

    /**
     * 返回参数的ulp大小。{@code double} 值的ulp（最后一位的单位）
     * 是此浮点值与下一个更大幅度的 {@code double} 值之间的正距离。
     * 注意，对于非NaN的 <i>x</i>，<code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>。
     *
     * <p>特殊情况：
     * <ul>
     * <li> 如果参数是NaN，则结果是NaN。
     * <li> 如果参数是正无穷大或负无穷大，则结果是正无穷大。
     * <li> 如果参数是正零或负零，则结果是 {@code Double.MIN_VALUE}。
     * <li> 如果参数是 &plusmn;{@code Double.MAX_VALUE}，
     * 则结果等于 2<sup>971</sup>。
     * </ul>
     *
     * @param d 要返回其ulp的浮点值
     * @return 参数的ulp大小
     * @author Joseph D. Darcy
     * @since 1.5
     */
    public static double ulp(double d) {
        int exp = getExponent(d);

        switch(exp) {
        case DoubleConsts.MAX_EXPONENT+1:       // NaN or infinity
            return Math.abs(d);

        case DoubleConsts.MIN_EXPONENT-1:       // zero or subnormal
            return Double.MIN_VALUE;

        default:
            assert exp <= DoubleConsts.MAX_EXPONENT && exp >= DoubleConsts.MIN_EXPONENT;

            // ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
            exp = exp - (DoubleConsts.SIGNIFICAND_WIDTH-1);
            if (exp >= DoubleConsts.MIN_EXPONENT) {
                return powerOfTwoD(exp);
            }
            else {
                // return a subnormal result; left shift integer
                // representation of Double.MIN_VALUE appropriate
                // number of positions
                return Double.longBitsToDouble(1L <<
                (exp - (DoubleConsts.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1)) ));
            }
        }
    }

    /**
     * 返回参数的ulp大小。{@code float} 值的ulp（最后一位的单位）
     * 是此浮点值与下一个更大幅度的 {@code float} 值之间的正距离。
     * 注意，对于非NaN的 <i>x</i>，<code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>。
     *
     * <p>特殊情况：
     * <ul>
     * <li> 如果参数是NaN，则结果是NaN。
     * <li> 如果参数是正无穷大或负无穷大，则结果是正无穷大。
     * <li> 如果参数是正零或负零，则结果是 {@code Float.MIN_VALUE}。
     * <li> 如果参数是 &plusmn;{@code Float.MAX_VALUE}，
     * 则结果等于 2<sup>104</sup>。
     * </ul>
     *
     * @param f 要返回其ulp的浮点值
     * @return 参数的ulp大小
     * @author Joseph D. Darcy
     * @since 1.5
     */
    public static float ulp(float f) {
        int exp = getExponent(f);

        switch(exp) {
        case FloatConsts.MAX_EXPONENT+1:        // NaN or infinity
            return Math.abs(f);

        case FloatConsts.MIN_EXPONENT-1:        // zero or subnormal
            return FloatConsts.MIN_VALUE;

        default:
            assert exp <= FloatConsts.MAX_EXPONENT && exp >= FloatConsts.MIN_EXPONENT;

            // ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
            exp = exp - (FloatConsts.SIGNIFICAND_WIDTH-1);
            if (exp >= FloatConsts.MIN_EXPONENT) {
                return powerOfTwoF(exp);
            }
            else {
                // return a subnormal result; left shift integer
                // representation of FloatConsts.MIN_VALUE appropriate
                // number of positions
                return Float.intBitsToFloat(1 <<
                (exp - (FloatConsts.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1)) ));
            }
        }
    }

    /**
     * 返回参数的符号函数；如果参数为零则为零，
     * 如果参数大于零则为1.0，如果参数小于零则为-1.0。
     *
     * <p>特殊情况：
     * <ul>
     * <li> 如果参数是NaN，则结果是NaN。
     * <li> 如果参数是正零或负零，则结果与参数相同。
     * </ul>
     *
     * @param d 要返回其符号的浮点值
     * @return 参数的符号函数
     * @author Joseph D. Darcy
     * @since 1.5
     */
    public static double signum(double d) {
        return (d == 0.0 || Double.isNaN(d))?d:copySign(1.0, d);
    }

    /**
     * 返回参数的符号函数；如果参数为零则为零，
     * 如果参数大于零则为1.0f，如果参数小于零则为-1.0f。
     *
     * <p>特殊情况：
     * <ul>
     * <li> 如果参数是NaN，则结果是NaN。
     * <li> 如果参数是正零或负零，则结果与参数相同。
     * </ul>
     *
     * @param f 要返回其符号的浮点值
     * @return 参数的符号函数
     * @author Joseph D. Darcy
     * @since 1.5
     */
    public static float signum(float f) {
        return (f == 0.0f || Float.isNaN(f))?f:copySign(1.0f, f);
    }

    /**
     * 返回 {@code double} 值的双曲正弦。
     * <i>x</i> 的双曲正弦定义为
     * (<i>e<sup>x</sup>&nbsp;-&nbsp;e<sup>-x</sup></i>)/2
     * 其中 <i>e</i> 是 {@linkplain Math#E 欧拉数}。
     *
     * <p>特殊情况：
     * <ul>
     *
     * <li>如果参数是NaN，则结果是NaN。
     *
     * <li>如果参数是无穷大，则结果是与参数符号相同的无穷大。
     *
     * <li>如果参数是零，则结果是与参数符号相同的零。
     *
     * </ul>
     *
     * <p>计算结果必须在精确结果的2.5 ulp范围内。
     *
     * @param   x 要返回其双曲正弦的数。
     * @return  {@code x} 的双曲正弦。
     * @since 1.5
     */
    public static double sinh(double x) {
        return StrictMath.sinh(x);
    }

    /**
     * 返回 {@code double} 值的双曲余弦。
     * <i>x</i> 的双曲余弦定义为
     * (<i>e<sup>x</sup>&nbsp;+&nbsp;e<sup>-x</sup></i>)/2
     * 其中 <i>e</i> 是 {@linkplain Math#E 欧拉数}。
     *
     * <p>特殊情况：
     * <ul>
     *
     * <li>如果参数是NaN，则结果是NaN。
     *
     * <li>如果参数是无穷大，则结果是正无穷大。
     *
     * <li>如果参数是零，则结果是 {@code 1.0}。
     *
     * </ul>
     *
     * <p>计算结果必须在精确结果的2.5 ulp范围内。
     *
     * @param   x 要返回其双曲余弦的数。
     * @return  {@code x} 的双曲余弦。
     * @since 1.5
     */
    public static double cosh(double x) {
        return StrictMath.cosh(x);
    }

    /**
     * 返回 {@code double} 值的双曲正切。
     * <i>x</i> 的双曲正切定义为
     * (<i>e<sup>x</sup>&nbsp;-&nbsp;e<sup>-x</sup></i>)/(<i>e<sup>x</sup>&nbsp;+&nbsp;e<sup>-x</sup></i>)，
     * 换句话说，{@linkplain Math#sinh
     * sinh(<i>x</i>)}/{@linkplain Math#cosh cosh(<i>x</i>)}。
     * 注意精确tanh的绝对值总是小于1。
     *
     * <p>特殊情况：
     * <ul>
     *
     * <li>如果参数是NaN，则结果是NaN。
     *
     * <li>如果参数是零，则结果是与参数符号相同的零。
     *
     * <li>如果参数是正无穷大，则结果是 {@code +1.0}。
     *
     * <li>如果参数是负无穷大，则结果是 {@code -1.0}。
     *
     * </ul>
     *
     * <p>计算结果必须在精确结果的2.5 ulp范围内。
     * 任何有限输入的 {@code tanh} 结果的绝对值必须小于或等于1。
     * 注意，一旦tanh的精确结果在极限值&plusmn;1的1/2 ulp范围内，
     * 应该返回正确符号的&plusmn;{@code 1.0}。
     *
     * @param   x 要返回其双曲正切的数。
     * @return  {@code x} 的双曲正切。
     * @since 1.5
     */
    public static double tanh(double x) {
        return StrictMath.tanh(x);
    }

    /**
     * Returns sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
     * without intermediate overflow or underflow.
     *
     * <p>Special cases:
     * <ul>
     *
     * <li> 如果任一参数是无穷大，则结果是正无穷大。
     *
     * <li> 如果任一参数是NaN且两个参数都不是无穷大，
     * 则结果是NaN。
     *
     * </ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 如果一个参数保持常数，结果在另一个参数中必须是半单调的。
     *
     * @param x 一个值
     * @param y 一个值
     * @return sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
     * 不会发生中间溢出或下溢
     * @since 1.5
     */
    public static double hypot(double x, double y) {
        return StrictMath.hypot(x, y);
    }

    /**
     * 返回 <i>e</i><sup>x</sup>&nbsp;-1。注意，对于接近0的 <i>x</i> 值，
     * {@code expm1(x)}&nbsp;+&nbsp;1 的精确和比 {@code exp(x)}
     * 更接近 <i>e</i><sup>x</sup> 的真实结果。
     *
     * <p>特殊情况：
     * <ul>
     * <li>如果参数是NaN，结果是NaN。
     *
     * <li>如果参数是正无穷大，则结果是正无穷大。
     *
     * <li>如果参数是负无穷大，则结果是-1.0。
     *
     * <li>如果参数是零，则结果是与参数符号相同的零。
     *
     * </ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 结果必须是半单调的。任何有限输入的 {@code expm1} 结果
     * 必须大于或等于 {@code -1.0}。注意，一旦
     * <i>e</i><sup>{@code x}</sup>&nbsp;-&nbsp;1 的精确结果
     * 在极限值-1的1/2 ulp范围内，应该返回 {@code -1.0}。
     *
     * @param   x   在计算 <i>e</i><sup>{@code x}</sup>&nbsp;-1 中
     *              <i>e</i> 的指数。
     * @return  值 <i>e</i><sup>{@code x}</sup>&nbsp;-&nbsp;1。
     * @since 1.5
     */
    public static double expm1(double x) {
        return StrictMath.expm1(x);
    }

    /**
     * 返回参数与1之和的自然对数。
     * 注意，对于小值 {@code x}，{@code log1p(x)} 的结果
     * 比 {@code log(1.0+x)} 的浮点计算更接近
     * ln(1 + {@code x}) 的真实结果。
     *
     * <p>特殊情况：
     *
     * <ul>
     *
     * <li>如果参数是NaN或小于-1，则结果是NaN。
     *
     * <li>如果参数是正无穷大，则结果是正无穷大。
     *
     * <li>如果参数是负一，则结果是负无穷大。
     *
     * <li>如果参数是零，则结果是与参数符号相同的零。
     *
     * </ul>
     *
     * <p>计算结果必须在精确结果的1 ulp范围内。
     * 结果必须是半单调的。
     *
     * @param   x   一个值
     * @return 值 ln({@code x}&nbsp;+&nbsp;1)，{@code x}&nbsp;+&nbsp;1 的自然对数
     * @since 1.5
     */
    public static double log1p(double x) {
        return StrictMath.log1p(x);
    }

    /**
     * 返回带有第二个浮点参数符号的第一个浮点参数。
     * 注意，与 {@link StrictMath#copySign(double, double) StrictMath.copySign}
     * 方法不同，此方法不要求将NaN {@code sign} 参数视为正值；
     * 允许实现将某些NaN参数视为正值，将其他NaN参数视为负值，
     * 以获得更好的性能。
     *
     * @param magnitude  提供结果幅度的参数
     * @param sign   提供结果符号的参数
     * @return 具有 {@code magnitude} 幅度和 {@code sign} 符号的值。
     * @since 1.6
     */
    public static double copySign(double magnitude, double sign) {
        return Double.longBitsToDouble((Double.doubleToRawLongBits(sign) &
                                        (DoubleConsts.SIGN_BIT_MASK)) |
                                       (Double.doubleToRawLongBits(magnitude) &
                                        (DoubleConsts.EXP_BIT_MASK |
                                         DoubleConsts.SIGNIF_BIT_MASK)));
    }

    /**
     * 返回带有第二个浮点参数符号的第一个浮点参数。
     * 注意，与 {@link StrictMath#copySign(float, float) StrictMath.copySign}
     * 方法不同，此方法不要求将NaN {@code sign} 参数视为正值；
     * 允许实现将某些NaN参数视为正值，将其他NaN参数视为负值，
     * 以获得更好的性能。
     *
     * @param magnitude  提供结果幅度的参数
     * @param sign   提供结果符号的参数
     * @return 具有 {@code magnitude} 幅度和 {@code sign} 符号的值。
     * @since 1.6
     */
    public static float copySign(float magnitude, float sign) {
        return Float.intBitsToFloat((Float.floatToRawIntBits(sign) &
                                     (FloatConsts.SIGN_BIT_MASK)) |
                                    (Float.floatToRawIntBits(magnitude) &
                                     (FloatConsts.EXP_BIT_MASK |
                                      FloatConsts.SIGNIF_BIT_MASK)));
    }

    /**
     * 返回 {@code float} 表示中使用的无偏指数。特殊情况：
     *
     * <ul>
     * <li>如果参数是NaN或无穷大，则结果是
     * {@link Float#MAX_EXPONENT} + 1。
     * <li>如果参数是零或次正规数，则结果是
     * {@link Float#MIN_EXPONENT} -1。
     * </ul>
     * @param f 一个 {@code float} 值
     * @return 参数的无偏指数
     * @since 1.6
     */
    public static int getExponent(float f) {
        /*
         * Bitwise convert f to integer, mask out exponent bits, shift
         * to the right and then subtract out float's bias adjust to
         * get true exponent value
         */
        return ((Float.floatToRawIntBits(f) & FloatConsts.EXP_BIT_MASK) >>
                (FloatConsts.SIGNIFICAND_WIDTH - 1)) - FloatConsts.EXP_BIAS;
    }

    /**
     * 返回 {@code double} 表示中使用的无偏指数。特殊情况：
     *
     * <ul>
     * <li>如果参数是NaN或无穷大，则结果是
     * {@link Double#MAX_EXPONENT} + 1。
     * <li>如果参数是零或次正规数，则结果是
     * {@link Double#MIN_EXPONENT} -1。
     * </ul>
     * @param d 一个 {@code double} 值
     * @return 参数的无偏指数
     * @since 1.6
     */
    public static int getExponent(double d) {
        /*
         * Bitwise convert d to long, mask out exponent bits, shift
         * to the right and then subtract out double's bias adjust to
         * get true exponent value.
         */
        return (int)(((Double.doubleToRawLongBits(d) & DoubleConsts.EXP_BIT_MASK) >>
                      (DoubleConsts.SIGNIFICAND_WIDTH - 1)) - DoubleConsts.EXP_BIAS);
    }

    /**
     * 返回在第二个参数方向上与第一个参数相邻的浮点数。
     * 如果两个参数比较相等，则返回第二个参数。
     *
     * <p>
     * 特殊情况：
     * <ul>
     * <li> 如果任一参数是NaN，则返回NaN。
     *
     * <li> 如果两个参数都是有符号零，则返回未更改的 {@code direction}
     * （如参数比较相等时返回第二个参数的要求所暗示的）。
     *
     * <li> 如果 {@code start} 是 &plusmn;{@link Double#MIN_VALUE}
     * 且 {@code direction} 的值使得结果应该具有更小的幅度，
     * 则返回与 {@code start} 符号相同的零。
     *
     * <li> 如果 {@code start} 是无穷大且 {@code direction} 的值
     * 使得结果应该具有更小的幅度，则返回与 {@code start}
     * 符号相同的 {@link Double#MAX_VALUE}。
     *
     * <li> 如果 {@code start} 等于 &plusmn;{@link Double#MAX_VALUE}
     * 且 {@code direction} 的值使得结果应该具有更大的幅度，
     * 则返回与 {@code start} 符号相同的无穷大。
     * </ul>
     *
     * @param start  起始浮点值
     * @param direction 指示应返回 {@code start} 的哪个邻居或 {@code start} 的值
     * @return 在 {@code direction} 方向上与 {@code start} 相邻的浮点数。
     * @since 1.6
     */
    public static double nextAfter(double start, double direction) {
        /*
         * The cases:
         *
         * nextAfter(+infinity, 0)  == MAX_VALUE
         * nextAfter(+infinity, +infinity)  == +infinity
         * nextAfter(-infinity, 0)  == -MAX_VALUE
         * nextAfter(-infinity, -infinity)  == -infinity
         *
         * are naturally handled without any additional testing
         */

        // First check for NaN values
        if (Double.isNaN(start) || Double.isNaN(direction)) {
            // return a NaN derived from the input NaN(s)
            return start + direction;
        } else if (start == direction) {
            return direction;
        } else {        // start > direction or start < direction
            // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
            // then bitwise convert start to integer.
            long transducer = Double.doubleToRawLongBits(start + 0.0d);

            /*
             * IEEE 754 floating-point numbers are lexicographically
             * ordered if treated as signed- magnitude integers .
             * Since Java's integers are two's complement,
             * incrementing" the two's complement representation of a
             * logically negative floating-point value *decrements*
             * the signed-magnitude representation. Therefore, when
             * the integer representation of a floating-point values
             * is less than zero, the adjustment to the representation
             * is in the opposite direction than would be expected at
             * first .
             */
            if (direction > start) { // Calculate next greater value
                transducer = transducer + (transducer >= 0L ? 1L:-1L);
            } else  { // Calculate next lesser value
                assert direction < start;
                if (transducer > 0L)
                    --transducer;
                else
                    if (transducer < 0L )
                        ++transducer;
                    /*
                     * transducer==0, the result is -MIN_VALUE
                     *
                     * The transition from zero (implicitly
                     * positive) to the smallest negative
                     * signed magnitude value must be done
                     * explicitly.
                     */
                    else
                        transducer = DoubleConsts.SIGN_BIT_MASK | 1L;
            }

            return Double.longBitsToDouble(transducer);
        }
    }

    /**
     * 返回在第二个参数方向上与第一个参数相邻的浮点数。
     * 如果两个参数比较相等，则返回等价于第二个参数的值。
     *
     * <p>
     * 特殊情况：
     * <ul>
     * <li> 如果任一参数是NaN，则返回NaN。
     *
     * <li> 如果两个参数都是有符号零，则返回等价于 {@code direction} 的值。
     *
     * <li> 如果 {@code start} 是 &plusmn;{@link Float#MIN_VALUE}
     * 且 {@code direction} 的值使得结果应该具有更小的幅度，
     * 则返回与 {@code start} 符号相同的零。
     *
     * <li> 如果 {@code start} 是无穷大且 {@code direction} 的值
     * 使得结果应该具有更小的幅度，则返回与 {@code start}
     * 符号相同的 {@link Float#MAX_VALUE}。
     *
     * <li> 如果 {@code start} 等于 &plusmn;{@link Float#MAX_VALUE}
     * 且 {@code direction} 的值使得结果应该具有更大的幅度，
     * 则返回与 {@code start} 符号相同的无穷大。
     * </ul>
     *
     * @param start  起始浮点值
     * @param direction 指示应返回 {@code start} 的哪个邻居或 {@code start} 的值
     * @return 在 {@code direction} 方向上与 {@code start} 相邻的浮点数。
     * @since 1.6
     */
    public static float nextAfter(float start, double direction) {
        /*
         * The cases:
         *
         * nextAfter(+infinity, 0)  == MAX_VALUE
         * nextAfter(+infinity, +infinity)  == +infinity
         * nextAfter(-infinity, 0)  == -MAX_VALUE
         * nextAfter(-infinity, -infinity)  == -infinity
         *
         * are naturally handled without any additional testing
         */

        // First check for NaN values
        if (Float.isNaN(start) || Double.isNaN(direction)) {
            // return a NaN derived from the input NaN(s)
            return start + (float)direction;
        } else if (start == direction) {
            return (float)direction;
        } else {        // start > direction or start < direction
            // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
            // then bitwise convert start to integer.
            int transducer = Float.floatToRawIntBits(start + 0.0f);

            /*
             * IEEE 754 floating-point numbers are lexicographically
             * ordered if treated as signed- magnitude integers .
             * Since Java's integers are two's complement,
             * incrementing" the two's complement representation of a
             * logically negative floating-point value *decrements*
             * the signed-magnitude representation. Therefore, when
             * the integer representation of a floating-point values
             * is less than zero, the adjustment to the representation
             * is in the opposite direction than would be expected at
             * first.
             */
            if (direction > start) {// Calculate next greater value
                transducer = transducer + (transducer >= 0 ? 1:-1);
            } else  { // Calculate next lesser value
                assert direction < start;
                if (transducer > 0)
                    --transducer;
                else
                    if (transducer < 0 )
                        ++transducer;
                    /*
                     * transducer==0, the result is -MIN_VALUE
                     *
                     * The transition from zero (implicitly
                     * positive) to the smallest negative
                     * signed magnitude value must be done
                     * explicitly.
                     */
                    else
                        transducer = FloatConsts.SIGN_BIT_MASK | 1;
            }

            return Float.intBitsToFloat(transducer);
        }
    }

    /**
     * 返回在正无穷大方向上与 {@code d} 相邻的浮点值。
     * 此方法在语义上等价于 {@code nextAfter(d, Double.POSITIVE_INFINITY)}；
     * 但是，{@code nextUp} 实现可能比其等价的 {@code nextAfter} 调用运行得更快。
     *
     * <p>特殊情况：
     * <ul>
     * <li> 如果参数是NaN，结果是NaN。
     *
     * <li> 如果参数是正无穷大，结果是正无穷大。
     *
     * <li> 如果参数是零，结果是 {@link Double#MIN_VALUE}
     *
     * </ul>
     *
     * @param d 起始浮点值
     * @return 更接近正无穷大的相邻浮点值。
     * @since 1.6
     */
    public static double nextUp(double d) {
        if( Double.isNaN(d) || d == Double.POSITIVE_INFINITY)
            return d;
        else {
            d += 0.0d;
            return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
                                           ((d >= 0.0d)?+1L:-1L));
        }
    }

    /**
     * 返回在正无穷大方向上与 {@code f} 相邻的浮点值。
     * 此方法在语义上等价于 {@code nextAfter(f, Float.POSITIVE_INFINITY)}；
     * 但是，{@code nextUp} 实现可能比其等价的 {@code nextAfter} 调用运行得更快。
     *
     * <p>特殊情况：
     * <ul>
     * <li> 如果参数是NaN，结果是NaN。
     *
     * <li> 如果参数是正无穷大，结果是正无穷大。
     *
     * <li> 如果参数是零，结果是 {@link Float#MIN_VALUE}
     *
     * </ul>
     *
     * @param f 起始浮点值
     * @return 更接近正无穷大的相邻浮点值。
     * @since 1.6
     */
    public static float nextUp(float f) {
        if( Float.isNaN(f) || f == FloatConsts.POSITIVE_INFINITY)
            return f;
        else {
            f += 0.0f;
            return Float.intBitsToFloat(Float.floatToRawIntBits(f) +
                                        ((f >= 0.0f)?+1:-1));
        }
    }

    /**
     * 返回在负无穷大方向上与 {@code d} 相邻的浮点值。
     * 此方法在语义上等价于 {@code nextAfter(d, Double.NEGATIVE_INFINITY)}；
     * 但是，{@code nextDown} 实现可能比其等价的 {@code nextAfter} 调用运行得更快。
     *
     * <p>特殊情况：
     * <ul>
     * <li> 如果参数是NaN，结果是NaN。
     *
     * <li> 如果参数是负无穷大，结果是负无穷大。
     *
     * <li> 如果参数是零，结果是 {@code -Double.MIN_VALUE}
     *
     * </ul>
     *
     * @param d  起始浮点值
     * @return 更接近负无穷大的相邻浮点值。
     * @since 1.8
     */
    public static double nextDown(double d) {
        if (Double.isNaN(d) || d == Double.NEGATIVE_INFINITY)
            return d;
        else {
            if (d == 0.0)
                return -Double.MIN_VALUE;
            else
                return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
                                               ((d > 0.0d)?-1L:+1L));
        }
    }

    /**
     * 返回在负无穷大方向上与 {@code f} 相邻的浮点值。
     * 此方法在语义上等价于 {@code nextAfter(f, Float.NEGATIVE_INFINITY)}；
     * 但是，{@code nextDown} 实现可能比其等价的 {@code nextAfter} 调用运行得更快。
     *
     * <p>特殊情况：
     * <ul>
     * <li> 如果参数是NaN，结果是NaN。
     *
     * <li> 如果参数是负无穷大，结果是负无穷大。
     *
     * <li> 如果参数是零，结果是 {@code -Float.MIN_VALUE}
     *
     * </ul>
     *
     * @param f  起始浮点值
     * @return 更接近负无穷大的相邻浮点值。
     * @since 1.8
     */
    public static float nextDown(float f) {
        if (Float.isNaN(f) || f == Float.NEGATIVE_INFINITY)
            return f;
        else {
            if (f == 0.0f)
                return -Float.MIN_VALUE;
            else
                return Float.intBitsToFloat(Float.floatToRawIntBits(f) +
                                            ((f > 0.0f)?-1:+1));
        }
    }

    /**
     * 返回 {@code d} &times; 2<sup>{@code scaleFactor}</sup>，
     * 舍入就像由单个正确舍入的浮点乘法执行到double值集的成员一样。
     * 有关浮点值集的讨论，请参见Java语言规范。
     * 如果结果的指数在 {@link Double#MIN_EXPONENT} 和
     * {@link Double#MAX_EXPONENT} 之间，则精确计算答案。
     * 如果结果的指数大于 {@code Double.MAX_EXPONENT}，
     * 则返回无穷大。注意，如果结果是次正规数，精度可能会丢失；
     * 也就是说，当 {@code scalb(x, n)} 是次正规数时，
     * {@code scalb(scalb(x, n), -n)} 可能不等于 <i>x</i>。
     * 当结果不是NaN时，结果与 {@code d} 具有相同的符号。
     *
     * <p>特殊情况：
     * <ul>
     * <li> 如果第一个参数是NaN，返回NaN。
     * <li> 如果第一个参数是无穷大，则返回相同符号的无穷大。
     * <li> 如果第一个参数是零，则返回相同符号的零。
     * </ul>
     *
     * @param d 要按2的幂缩放的数。
     * @param scaleFactor 用于缩放 {@code d} 的2的幂
     * @return {@code d} &times; 2<sup>{@code scaleFactor}</sup>
     * @since 1.6
     */
    public static double scalb(double d, int scaleFactor) {
        /*
         * This method does not need to be declared strictfp to
         * compute the same correct result on all platforms.  When
         * scaling up, it does not matter what order the
         * multiply-store operations are done; the result will be
         * finite or overflow regardless of the operation ordering.
         * However, to get the correct result when scaling down, a
         * particular ordering must be used.
         *
         * When scaling down, the multiply-store operations are
         * sequenced so that it is not possible for two consecutive
         * multiply-stores to return subnormal results.  If one
         * multiply-store result is subnormal, the next multiply will
         * round it away to zero.  This is done by first multiplying
         * by 2 ^ (scaleFactor % n) and then multiplying several
         * times by by 2^n as needed where n is the exponent of number
         * that is a covenient power of two.  In this way, at most one
         * real rounding error occurs.  If the double value set is
         * being used exclusively, the rounding will occur on a
         * multiply.  If the double-extended-exponent value set is
         * being used, the products will (perhaps) be exact but the
         * stores to d are guaranteed to round to the double value
         * set.
         *
         * It is _not_ a valid implementation to first multiply d by
         * 2^MIN_EXPONENT and then by 2 ^ (scaleFactor %
         * MIN_EXPONENT) since even in a strictfp program double
         * rounding on underflow could occur; e.g. if the scaleFactor
         * argument was (MIN_EXPONENT - n) and the exponent of d was a
         * little less than -(MIN_EXPONENT - n), meaning the final
         * result would be subnormal.
         *
         * Since exact reproducibility of this method can be achieved
         * without any undue performance burden, there is no
         * compelling reason to allow double rounding on underflow in
         * scalb.
         */

        // magnitude of a power of two so large that scaling a finite
        // nonzero value by it would be guaranteed to over or
        // underflow; due to rounding, scaling down takes takes an
        // additional power of two which is reflected here
        final int MAX_SCALE = DoubleConsts.MAX_EXPONENT + -DoubleConsts.MIN_EXPONENT +
                              DoubleConsts.SIGNIFICAND_WIDTH + 1;
        int exp_adjust = 0;
        int scale_increment = 0;
        double exp_delta = Double.NaN;

        // Make sure scaling factor is in a reasonable range

        if(scaleFactor < 0) {
            scaleFactor = Math.max(scaleFactor, -MAX_SCALE);
            scale_increment = -512;
            exp_delta = twoToTheDoubleScaleDown;
        }
        else {
            scaleFactor = Math.min(scaleFactor, MAX_SCALE);
            scale_increment = 512;
            exp_delta = twoToTheDoubleScaleUp;
        }

        // Calculate (scaleFactor % +/-512), 512 = 2^9, using
        // technique from "Hacker's Delight" section 10-2.
        int t = (scaleFactor >> 9-1) >>> 32 - 9;
        exp_adjust = ((scaleFactor + t) & (512 -1)) - t;

        d *= powerOfTwoD(exp_adjust);
        scaleFactor -= exp_adjust;

        while(scaleFactor != 0) {
            d *= exp_delta;
            scaleFactor -= scale_increment;
        }
        return d;
    }

    /**
     * 返回 {@code f} &times; 2<sup>{@code scaleFactor}</sup>，
     * 舍入就像由单个正确舍入的浮点乘法执行到float值集的成员一样。
     * 有关浮点值集的讨论，请参见Java语言规范。
     * 如果结果的指数在 {@link Float#MIN_EXPONENT} 和
     * {@link Float#MAX_EXPONENT} 之间，则精确计算答案。
     * 如果结果的指数大于 {@code Float.MAX_EXPONENT}，
     * 则返回无穷大。注意，如果结果是次正规数，精度可能会丢失；
     * 也就是说，当 {@code scalb(x, n)} 是次正规数时，
     * {@code scalb(scalb(x, n), -n)} 可能不等于 <i>x</i>。
     * 当结果不是NaN时，结果与 {@code f} 具有相同的符号。
     *
     * <p>特殊情况：
     * <ul>
     * <li> 如果第一个参数是NaN，返回NaN。
     * <li> 如果第一个参数是无穷大，则返回相同符号的无穷大。
     * <li> 如果第一个参数是零，则返回相同符号的零。
     * </ul>
     *
     * @param f 要按2的幂缩放的数。
     * @param scaleFactor 用于缩放 {@code f} 的2的幂
     * @return {@code f} &times; 2<sup>{@code scaleFactor}</sup>
     * @since 1.6
     */
    public static float scalb(float f, int scaleFactor) {
        // magnitude of a power of two so large that scaling a finite
        // nonzero value by it would be guaranteed to over or
        // underflow; due to rounding, scaling down takes takes an
        // additional power of two which is reflected here
        final int MAX_SCALE = FloatConsts.MAX_EXPONENT + -FloatConsts.MIN_EXPONENT +
                              FloatConsts.SIGNIFICAND_WIDTH + 1;

        // Make sure scaling factor is in a reasonable range
        scaleFactor = Math.max(Math.min(scaleFactor, MAX_SCALE), -MAX_SCALE);

        /*
         * Since + MAX_SCALE for float fits well within the double
         * exponent range and + float -> double conversion is exact
         * the multiplication below will be exact. Therefore, the
         * rounding that occurs when the double product is cast to
         * float will be the correctly rounded float result.  Since
         * all operations other than the final multiply will be exact,
         * it is not necessary to declare this method strictfp.
         */
        return (float)((double)f*powerOfTwoD(scaleFactor));
    }

    // Constants used in scalb
    static double twoToTheDoubleScaleUp = powerOfTwoD(512);
    static double twoToTheDoubleScaleDown = powerOfTwoD(-512);

    /**
     * 返回正常范围内的2的浮点幂。
     */
    static double powerOfTwoD(int n) {
        assert(n >= DoubleConsts.MIN_EXPONENT && n <= DoubleConsts.MAX_EXPONENT);
        return Double.longBitsToDouble((((long)n + (long)DoubleConsts.EXP_BIAS) <<
                                        (DoubleConsts.SIGNIFICAND_WIDTH-1))
                                       & DoubleConsts.EXP_BIT_MASK);
    }

    /**
     * 返回正常范围内的2的浮点幂。
     */
    static float powerOfTwoF(int n) {
        assert(n >= FloatConsts.MIN_EXPONENT && n <= FloatConsts.MAX_EXPONENT);
        return Float.intBitsToFloat(((n + FloatConsts.EXP_BIAS) <<
                                     (FloatConsts.SIGNIFICAND_WIDTH-1))
                                    & FloatConsts.EXP_BIT_MASK);
    }
}
